package com.sdhs.paas.sdk.core.environment;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.stream.Collectors;

import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.test.context.TestContext;
import org.springframework.util.Assert;

/**
 * 封装springcloud的环境配置
 *
 * @author wjj
 *
 */
public class EnviromentBuilder {

	public static String[] buildAppEnv(String...args){

		SimpleCommandLinePropertySource argsMap = new SimpleCommandLinePropertySource(args);
		String appName = argsMap.getProperty("sdgs.app.name");
//		String basepkg = argsMap.getProperty("shtelpaas.app.basepkg");
		String regitries = argsMap.getProperty("sdgs.app.nameserver");
		regitries = regitries == null ? "http://localhost:9003/eureka/" : regitries;
		String cfgserver = argsMap.getProperty("sdgs.app.configserver");
		cfgserver = cfgserver == null ? "sdgsConfigserver" : cfgserver;
//		String cfgprofile = argsMap.getProperty("shtelpaas.app.config.profile");
//		cfgprofile = cfgprofile == null ? "base$dev$1.0,app$dev$1.0" : cfgprofile;
//		String logprofile = argsMap.getProperty("shtelpaas.log.profile");
//		logprofile = logprofile == null ? "log$dev$1.0" : logprofile;
		String cfgmode = argsMap.getProperty("sdgs.app.config.mode");
		cfgmode = cfgmode == null ? "remote" : cfgmode;

		Assert.notNull(appName, "PaasMainApp 启动！应用名称(shtelpaas.app.name)参数未定义！");
//		Assert.notNull(basepkg, "PaasMainApp 启动！应用名称(shtelpaas.app.basepkg)参数未定义！");
		Assert.state(!appName.contains("-"), "PaasMainApp 启动！应用名称(shtelpaas.app.name)中不允许使用'-'号！");
		
		Map<String, String> pair = new HashMap<>();
		pair.put("spring.application.name", String.format("--spring.application.name=%s", appName));
		pair.put("eureka.client.serviceUrl.defaultZone",
				String.format("--eureka.client.serviceUrl.defaultZone=%s", regitries));
		pair.put("spring.cloud.config.discovery.serviceId",
				String.format("--spring.cloud.config.discovery.serviceId=%s", cfgserver));
//		pair.put("spring.cloud.config.profile", String.format("--spring.cloud.config.profile=%s", cfgprofile));
		
		
		if(cfgmode.equals("local")){
			pair.put("spring.config.location", "--spring.config.location=classpath:/paasapplication.yml,classpath:/subapplication.yml");
			pair.put("spring.cloud.bus.enabled", "--spring.cloud.bus.enabled=false");
			pair.put("spring.cloud.config.enabled", "--spring.cloud.config.enabled=false");
		}
		
		String[] newargs = replaceOrPutArrContent(args, pair);

//		PaasLogger.info("PaasMainApp 启动！应用名称:{}，根包路径:{}，注册中心地址:{}，配置中心服务名:{}，应用环境参数:{}，日志环境参数:{}", appName, basepkg,
//				regitries, cfgserver, cfgprofile, logprofile);
		
		
		return newargs;
		
	}
	
	public static void buildTestEnv(TestContext testContext) throws IOException, URISyntaxException{
		Class<?> cls = testContext.getTestClass();
		String PROPERTIES_FILE_NAME = cls.getSimpleName() + ".properties";
		InputStream ips = cls.getResourceAsStream(PROPERTIES_FILE_NAME);
		Properties argsMap = new Properties();
		argsMap.load(ips);
		ips.close();

		String appName = argsMap.getProperty("shtelpaas.app.name");
		// String basepkg = argsMap.getProperty("shtelpaas.app.basepkg");
		String regitries = argsMap.getProperty("shtelpaas.app.nameserver");
		regitries = regitries == null ? "http://localhost:8761/eureka/" : regitries;
		String cfgserver = argsMap.getProperty("shtelpaas.app.configserver");
		cfgserver = cfgserver == null ? "shtel-paas-configserver" : cfgserver;
		String cfgprofile = argsMap.getProperty("shtelpaas.app.config.profile");
		cfgprofile = cfgprofile == null ? "base$dev$1.0,app$dev$1.0" : cfgprofile;
		String logprofile = argsMap.getProperty("shtelpaas.log.profile");
		logprofile = logprofile == null ? "log$dev$1.0" : logprofile;
		String cfgmode = argsMap.getProperty("shtelpaas.app.config.mode");
		cfgmode = cfgmode == null ? "remote" : cfgmode;
		

		argsMap.put("spring.application.name", appName);
		argsMap.put("eureka.client.serviceUrl.defaultZone", regitries);
		argsMap.put("spring.cloud.config.discovery.serviceId", cfgserver);
		argsMap.put("spring.cloud.config.profile", cfgprofile);
		if(cfgmode.equals("local")){
			argsMap.put("spring.config.location", "classpath:/paasapplication.yml,classpath:/subapplication.yml");
			argsMap.put("spring.cloud.bus.enabled", "false");
			argsMap.put("spring.cloud.config.enabled", "false");
		}else{
			argsMap.remove("spring.config.location");
			argsMap.remove("spring.cloud.bus.enabled");
			argsMap.remove("spring.cloud.config.enabled");
		}

		argsMap.entrySet().forEach(e->((String)e.getValue()).trim());
		
		URL fileUrl = cls.getResource(PROPERTIES_FILE_NAME);// 得到文件路径
		FileOutputStream fos = new FileOutputStream(new File(fileUrl.toURI()));
		argsMap.store(fos, "PaasTestExecutionListener Created Properties File");
		fos.close();
	}
	
	/**
	 * 根据map内容替换或者增加数组内容
	 * 
	 * @param arr
	 *            源数组
	 * @param pair
	 *            原始内容和替换内容映射map
	 * @return 新数组
	 */
	public static String[] replaceOrPutArrContent(String[] arr, Map<String, String> pair) {
		List<String> arrLst = Arrays.asList(arr);

		List<String> chgedLst = arrLst.stream().map(s -> {
			List<Entry<String, String>> matchPair = pair.entrySet().stream().filter(e -> s.contains(e.getKey()))
					.collect(Collectors.toList());
			if (matchPair.size() > 0) {
				return matchPair.get(0).getValue();
			} else {
				return s;
			}
		}).collect(Collectors.toList());
		pair.entrySet().stream().forEach(e -> {
			if (!chgedLst.contains(e.getValue())) {
				chgedLst.add(e.getValue());
			}
		});
		String[] newarr = new String[chgedLst.size()];
		chgedLst.stream().forEach(e -> {e.trim();});
		chgedLst.toArray(newarr);
		return newarr;
	}
}
